#pragma once

#include <cstdint>
#include <atomic>
#include "viml/value_fwd.h"

namespace viml {

/**
 * 对象头部信息
 * 包含垃圾回收所需的元数据
 */
struct ObjectHeader {
    // 对象类型标记
    enum class Type : uint8_t {
        STRING = 1,
        LIST = 2,
        DICT = 3,
        FUNCTION = 4,
        CLOSURE = 5,
        BUILTIN = 6,
        // 可以扩展更多类型
    };

    Type type;           // 对象类型
    uint8_t generation;   // 分代GC中的代号
    bool marked : 1;     // 标记位，用于标记-清除算法
    bool forwarded : 1;   // 转发标记，用于对象移动
    uint32_t magic;     // 魔数，用于调试

    ObjectHeader(Type t = Type::STRING, uint8_t gen = 0)
        : type(t), generation(gen), marked(false), forwarded(false), magic(0xDEADBEEF) {}
};

/**
 * 基础对象类
 * 所有堆分配对象的基类，包含垃圾回收所需的基本信息
 */
class Object {
private:
    ObjectHeader header_;
    std::atomic<int> ref_count_;

public:
    explicit Object(ObjectHeader::Type type)
        : header_(type), ref_count_(1) {}  // 初始引用计数为1（创建者引用）

    virtual ~Object() {
        // 注意：不要在析构函数中调用纯虚函数
        // cleanup() 应该在引用计数归零时显式调用
    }

    // 获取对象头部信息
    const ObjectHeader& header() const { return header_; }

    // 引用计数操作
    void ref() {
        ref_count_.fetch_add(1, std::memory_order_relaxed);
    }

    void unref() {
        if (ref_count_.fetch_sub(1, std::memory_order_acq_rel) <= 1) {
            cleanup();  // 先调用清理
            delete this;
        }
    }

    int get_ref_count() const {
        return ref_count_.load(std::memory_order_acquire);
    }

    // 类型检查
    bool is_string() const { return header_.type == ObjectHeader::Type::STRING; }
    bool is_list() const { return header_.type == ObjectHeader::Type::LIST; }
    bool is_dict() const { return header_.type == ObjectHeader::Type::DICT; }
    bool is_function() const { return header_.type == ObjectHeader::Type::FUNCTION; }
    bool is_closure() const { return header_.type == ObjectHeader::Type::CLOSURE; }

    // 垃圾回收支持
    void mark() { header_.marked = true; }
    void unmark() { header_.marked = false; }
    bool is_marked() const { return header_.marked; }

    void set_generation(uint8_t gen) { header_.generation = gen; }
    uint8_t get_generation() const { return header_.generation; }

    // 转发支持（用于GC时的对象移动）
    void set_forwarded() { header_.forwarded = true; }
    void set_forwarded(bool forwarded) { header_.forwarded = forwarded; }
    bool is_forwarded() const { return header_.forwarded; }

    // 调试支持
    bool is_valid_object() const { return header_.magic == 0xDEADBEEF; }
    void set_magic() { header_.magic = 0xDEADBEEF; }

    // 虚析构函数，确保正确清理
    virtual void cleanup() = 0;

protected:
    // 受保护的清理方法，供派生类重写
    virtual void do_cleanup() = 0;
};

/**
 * 对象智能指针
 * 自动管理引用计数的智能指针包装器
 */
template<typename T>
class ObjPtr {
private:
    T* ptr_;

public:
    // 构造函数
    explicit ObjPtr(T* ptr = nullptr) : ptr_(ptr) {
        if (ptr_) {
            ptr_->ref();
        }
    }

    // 拷贝构造
    ObjPtr(const ObjPtr& other) : ptr_(other.ptr_) {
        if (ptr_) {
            ptr_->ref();
        }
    }

    // 移动构造
    ObjPtr(ObjPtr&& other) noexcept : ptr_(other.ptr_) {
        other.ptr_ = nullptr;
    }

    // 析构函数
    ~ObjPtr() {
        if (ptr_) {
            ptr_->unref();
        }
    }

    // 赋值操作
    ObjPtr& operator=(const ObjPtr& other) {
        if (this != &other) {
            if (ptr_) {
                ptr_->unref();
            }
            ptr_ = other.ptr_;
            if (ptr_) {
                ptr_->ref();
            }
        }
        return *this;
    }

    // 移动赋值
    ObjPtr& operator=(ObjPtr&& other) noexcept {
        if (this != &other) {
            if (ptr_) {
                ptr_->unref();
            }
            ptr_ = other.ptr_;
            other.ptr_ = nullptr;
        }
        return *this;
    }

    // 访问操作符
    T& operator*() const { return *ptr_; }
    T* operator->() const { return ptr_; }
    T* get() const { return ptr_; }

    // 比较操作
    bool operator==(const ObjPtr& other) const { return ptr_ == other.ptr_; }
    bool operator!=(const ObjPtr& other) const { return ptr_ != other.ptr_; }
    bool operator==(std::nullptr_t) const { return ptr_ == nullptr; }
    bool operator!=(std::nullptr_t) const { return ptr_ != nullptr; }

    // 重置
    void reset() {
        if (ptr_) {
            ptr_->unref();
            ptr_ = nullptr;
        }
    }

    // 释放所有权
    T* release() {
        T* temp = ptr_;
        ptr_ = nullptr;
        return temp;
    }
};

// 类型别名
using StringPtr = ObjPtr<class StringObject>;
using ListPtr = ObjPtr<class ListObject>;
using DictPtr = ObjPtr<class DictObject>;
using FunctionPtr = ObjPtr<class Function>;
using ClosurePtr = ObjPtr<class Closure>;

} // namespace viml